package com.apes.framework.util.monitor.threadPool;

import com.apes.oap.RopContext;
import com.apes.oap.ServiceRouter;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

@Service
public class ThreadPoolService implements DisposableBean {
    private MonitorTask monitorTask;

    @Value("${apes.threadPool.enable:false}")
    private boolean enable = false;

    public ThreadPoolService(ServiceRouter serviceRouter) {
        if (!enable) return;
        RopContext context = serviceRouter.getRopContext();
        ThreadPoolExecutor executor = (ThreadPoolExecutor) context.getThreadPoolExecutor();
        monitorTask = new MonitorTask(executor, 5);
        new Thread(monitorTask).start();
    }

    @Override
    public void destroy() {
        if (monitorTask == null) return;
        monitorTask.shutdown();
    }


    /**
     * 监听器
     **/
    class MonitorTask implements Runnable {
        protected final Log logger = LogFactory.getLog(this.getClass());

        // 被监控的executor
        private final ThreadPoolExecutor executor;
        // 监控间隔
        private final int seconds;
        // 监控开关
        private boolean run = true;

        public MonitorTask(ThreadPoolExecutor executor, int seconds) {
            this.executor = executor;
            this.seconds = seconds;
        }

        public void shutdown() {
            this.run = false;
        }

        @Override
        public void run() {
            while (run) {
                logger.debug(
                        String.format("[threadPool monitor] MaxPoolSize: %d, CorePoolSize: %d, PoolSize: %d, Queue: %d, Tasks: %d, Completed: %d, Active: %d, isShutdown: %s, isTerminated: %s",
                                this.executor.getMaximumPoolSize(),
                                this.executor.getCorePoolSize(),
                                this.executor.getPoolSize(),
                                this.executor.getQueue().size(),
                                this.executor.getTaskCount(),
                                this.executor.getCompletedTaskCount(),
                                this.executor.getActiveCount(),
                                this.executor.isShutdown(),
                                this.executor.isTerminated()));
                try {
                    TimeUnit.SECONDS.sleep(seconds);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}
